// 基类，建议所有自定义类均继承该类
export class Matrix{
    private _ref:number = 0;
    constructor(){
        this._ref = 1;
    }

    public init(...args: any[]){
        var _len: number = args.length;
        switch(_len){
            case 0:this.onInit();break;
            case 1:this.onInit(args[0]);break;
            case 2:this.onInit(args[0], args[1]);break;
            case 3:this.onInit(args[0], args[1], args[2]);break;
            case 4:this.onInit(args[0], args[1], args[2], args[3]);break;
            case 5:this.onInit(args[0], args[1], args[2], args[3], args[4]);break;
            default : break;
        }
    }

    public destroy(){
        --this._ref;
        if (this._ref < 1) {
            this._ref = 0;
            this.onDestroy();
            let self = this;
            self = null;
        }
    }

    public getRefCount():number{
        return this._ref;
    }

    public retain():number{
        return ++this._ref;
    }

    protected onInit(...param: any[]){
        // 子类实现
    }

    protected onDestroy(){
        // 子类实现
    }
}

// 单件
export class Singleton<T> extends Matrix{
    private _instance:T = null;
    constructor(){
        super();
    }

    public static getInstance<T>(o: { new(): T }): T {
        if (this.prototype._instance == null) {
            this.prototype._instance = new o();
        }
        return this.prototype._instance as T;
    }
}

/**
 * 网络数据处理
 * 仅仅只负责协议的加解密和心跳包的数据组织，派生类实现protected方法
 */
export interface PkgData  {proto:string,data:any}; // 解析后包结构定义
export class SocketParser extends Matrix{
    protected isStrMsg:boolean;
    public get isString():boolean{return this.isStrMsg;}
    public encode(data:any):any{return this.onEncode(data);}
    public sendHeartbeat():void{this.onHeartbeat();}
    public message(proto:string,data:any):void{this.onMessage(proto,data);}
    public decode(data:any):PkgData{return this.onDeconde(data);}

    protected onEncode(data:any):any{return null;}
    protected onDeconde(data:any):PkgData{return null;}
    protected onHeartbeat(){}
    protected onMessage(proto:string,data:any){}
}